package com.web.springutil;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;


public class SQLBuilder {
	private static Logger logger = Logger.getLogger(SQLBuilder.class);

	private Map<String, String> sqlContainer = null;

	private String sqlFilePath = "test.xml";

	public SQLBuilder() {
		initSqlContainer();
	}

	public SQLBuilder(String sqlFilePath) {
		this.sqlFilePath = sqlFilePath;
		initSqlContainer();
	}

	public String getSql(String key) {
		String sql = sqlContainer.get(key);
		if (sql == null || "".equals(sql))
			logger.warn("不存在该SQL语句");
		if (logger.isDebugEnabled()) {
			logger.debug("SQL:" + sql);
		}
		return sql;
	}

	public String getDynamicalSql(String key, Map<String, ?> param) {
		String sql = sqlContainer.get(key);
		return VelocityUtils.render(sql, param);
	}

	private void initSqlContainer() {
		sqlContainer = new ConcurrentHashMap<String, String>();
		if (sqlFilePath == null || "".equals(sqlFilePath)) {
			throw new NullPointerException("sql语句文件不能为空!");
		}
		String[] files = sqlFilePath.split(";");
		for (String file : files) {
			readSQLFromFile(file);
		}
	}
	
	private void readSQLFromFile(InputStream ips) {
		Document document = null;
		SAXReader saxReader = new SAXReader();
		try {
			document = saxReader.read(ips);
		} catch (DocumentException e) {
			e.printStackTrace();
			logger.error("读取系统中用到的SQL 语句XML出错");
			throw new RuntimeException("读取sql语句XML文件出错:" + e.getMessage());
		}
		Element root = document.getRootElement();
		List<Element> sqlElements = root.selectNodes("//sqlElement");
		String key;
		for (Element sql : sqlElements) {
			key = sql.attribute("key").getValue();
			if (sqlContainer.containsKey(key)) {
				logger.warn("key值:" + key + "重复");
			}
			sqlContainer.put(key, sql.getText());
		}

		if (ips != null) {
			try {
				ips.close();
			} catch (IOException e) {
				logger.error("关闭输入流出错:" + e.getMessage());
			}
		}
	}

	private void readSQLFromFile(String fileName) {
		InputStream ips = null;
		try {
			ips = new FileInputStream(fileName);
			readSQLFromFile(ips);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
	}

	public void setSqlFilePath(String sqlFilePath) {
		this.sqlFilePath = sqlFilePath;
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		if (sqlContainer != null) {
			sqlContainer.clear();
			sqlContainer = null;
		}
	}
}
